package com.fone.player.billing.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.zip.GZIPInputStream;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.SystemClock;

import com.fone.player.ApplicationManage;
import com.fone.player.entity.HttpFuture;
import com.fone.player.util.L;


public class HttpUtil {
	public static final String TAG = "HttpUtil";
	
	private static final int CONNECTION_TIMEOUT = 20 * 1000;
	private static final int TIMEOUT = 20 * 1000;
	
//	private static final int COUNT = 4;
	private static final int REQUEST_OK = 1;
	private static final int REQUEST_ERROR = -1;
	private static final int REQUEST_TIMEOUT = -2;
	
	/**
	 * judging network
	 */
	public static boolean hasNetwork() {
		ConnectivityManager con = (ConnectivityManager) ApplicationManage.getGlobalContext().getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo workinfo = con.getActiveNetworkInfo();
		if (workinfo == null || !workinfo.isAvailable()) {
			return false;
		}
		return true;
	}
	
	@SuppressWarnings("deprecation")
	private static String getProxyInfo() {
		L.v("NetUtil", "getProxyInfo", "begin");
		ConnectivityManager conMan = (ConnectivityManager) ApplicationManage.getGlobalContext().getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = conMan.getActiveNetworkInfo();
		if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE) {
			String host = android.net.Proxy.getDefaultHost();
			if (host != null) {
				StringBuffer proxy = new StringBuffer(host);
				proxy.append(":").append(android.net.Proxy.getDefaultPort());
				L.v("NetUtil", "getProxyInfo", proxy.toString());
				return proxy.toString();
			}
		}
		L.v("NetUtil", "getProxyInfo", "null");
		return null;
	}
	@SuppressWarnings("deprecation")
	public static HttpHost parseProxyHost(String params){
		HttpHost httpHost = null;
		try{
//			String ui_name =  ApplicationManage.getAplicationManageInstance()
			Uri uri = Uri.parse("content://telephony/carriers/preferapn");
			Cursor mCursor = ApplicationManage.getGlobalContext().getContentResolver().query(uri, null, null, null, null);//AppAplication.getGlobalContext().getContentResolver().query(uri, null, null, null, null);
			if (mCursor != null && mCursor.moveToFirst()) {
				String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy"));
				int proPort = android.net.Proxy.getDefaultPort();
				if (proxyStr != null && proxyStr.trim().length() > 0) {
					httpHost = new HttpHost(proxyStr, proPort);
				}
			}
			if(httpHost == null){
				String proHost = android.net.Proxy.getDefaultHost();
				httpHost = new HttpHost(proHost, 80);
			}
			mCursor.close();
		}catch(Exception e){
			e.printStackTrace();
		}
        return httpHost;
		
	}
	public static DefaultHttpClient getHttpClient() {
		HttpParams params = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
		HttpConnectionParams.setSoTimeout(params, TIMEOUT);
		
		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		
		DefaultHttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,registry), params);
		client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler());
		String proxy = getProxyInfo();
		if(null != proxy && proxy.length() > 0){
			client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, parseProxyHost(proxy));
		}
		return client;
	}

	public static byte[] sendHttpRequest(String url) {
		HttpFuture httpFuture = doGet(url);
		if (httpFuture.requestResult != REQUEST_OK) {
			String tempUrl = url;
				httpFuture = retryHttpRequest(tempUrl);
				switch (httpFuture.requestResult) {
				case REQUEST_ERROR:
					L.i(TAG, "REQUEST_ERROR", " changeHost  retry ");
					httpFuture = doGet(tempUrl);
					break;
				case REQUEST_TIMEOUT:
					httpFuture = retryHttpRequest(tempUrl);
					if (httpFuture.requestResult != REQUEST_OK) {
						HttpFuture httpFutureBd = visitBaidu();
						if (httpFutureBd.requestResult == REQUEST_OK) {
							L.i(TAG, "visitBaidu", " changeHost retry again ");
							httpFuture = doGet(tempUrl);
						} else {
							return httpFuture.data;
						}
					}
					break;
				}
		}
		return httpFuture.data;
	}
	
	public static HttpFuture doGet(String url) {
		L.i(TAG, "httpGet", url);
		DefaultHttpClient client = getHttpClient();
		HttpFuture httpFuture = new HttpFuture();
		try {
		HttpGet get = new HttpGet(url);
		get.setHeader("Accept", "*/*");
		get.setHeader("User-Agent", "(C)NokiaE5-00/SymbianOS/9.1 Series60/3.0");
		get.setHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
		get.addHeader("Accept-Encoding", "gzip,deflate"); 
		HttpResponse response = client.execute(get);
			if (null != response) {
				int code = response.getStatusLine().getStatusCode();
				L.i(TAG, "httpGet", " HttpStatus : " + code);
				switch (code) {
				case HttpStatus.SC_OK:
					httpFuture.data = writeByteArray(response);
					if (httpFuture.data != null) {
						httpFuture.requestResult = REQUEST_OK;
					} else {
						httpFuture.requestResult = REQUEST_ERROR;
					}
					break;

				case HttpStatus.SC_NOT_FOUND:
				case HttpStatus.SC_INTERNAL_SERVER_ERROR:
				case HttpStatus.SC_NOT_ACCEPTABLE:
					httpFuture.requestResult = REQUEST_ERROR;
					break;
				}
			}
		} catch (Exception e) {
			L.i(TAG, "httpGet", e.toString());
			if (e instanceof UnknownHostException || e instanceof HttpHostConnectException) {
				httpFuture.requestResult = REQUEST_ERROR;
			} else if (e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException) {
				httpFuture.requestResult = REQUEST_TIMEOUT;
			}
		} finally {
			L.v(TAG, "httpGet", " httpFuture.requestResult >>>"+ httpFuture.requestResult);
			closeHttpConnection(client);
			
		}
//		if(url.contains("preln?")||url.contains("alh?")|| url.contains("specllist?")||url.contains("xyzplay?")){ 
			if (null != httpFuture.data) {
				if(url.contains("/preln?")|| url.contains("/pb?")|| url.contains("/st?")||url.contains("/cou?")){
					byte[] data = decoding(httpFuture.data);
					String ptlFlag = "PTL";
					if (ptlFlag.equals(new String(data, 0, 3))) {
						httpFuture.data = data;
					} 
				}
				L.i(TAG, "httpGet", "http response : " +new String(httpFuture.data));
			} else {
				L.i(TAG, "httpGet", "http response is nothing.");
			}
//		}
		return httpFuture;
	}
	
	private static byte[] decoding (byte[] data) {
		int length = data.length;
		for (int i = 0; i < length; ++i) {
			data[i] -= (0x70 + i % 16);
		}
		return data;
	}
	
	private static HttpFuture retryHttpRequest (String url) {
		HttpFuture httpFuture = new HttpFuture();
		for (int i = 0; i < 3; i++) {
			L.v(TAG, "REQUEST_ERROR", " retry count : " + i);
			httpFuture = doGet(url);
			if (httpFuture.requestResult == REQUEST_OK) {
				L.i(TAG, "REQUEST_ERROR", " retry break ");
				break;
			}
			SystemClock.sleep(1000);
		}
		return httpFuture;
	} 

	private static HttpFuture visitBaidu() {
		// 访问百度
		String url = "http://wap.baidu.com";
		return doGet(url);
	}
	
	
	private static int getShort(byte[] data) {
		int header = (data[0] << 8) | data[1] & 0xFF;
		L.v("HttpThread", "HttpThread  getshort header ", (header == 0x1f8b));
		return header;
	}
	public static InputStream parseInputStream(InputStream inputStream) {
		BufferedInputStream bis = new BufferedInputStream(inputStream);
		InputStream in = null;
		try {
			bis.mark(2);
			// 取前两个字节
			byte[] header = new byte[2];
			int result = bis.read(header);
			// reset输入流到开始位置
			bis.reset();
			// 判断是否是GZIP格式
			int headerData = getShort(header);
			if (result != -1 && headerData == 0x1f8b) {
				in = new GZIPInputStream(bis);
			} else {
				in = bis;
			}
			return in;
		} catch (Exception e) {
			e.printStackTrace();
			return bis;
		}
	}
	private static byte[] writeByteArray(HttpResponse response) {
		try {
			InputStream inputstream = response.getEntity().getContent();
			InputStream in = parseInputStream(inputstream);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int len = 0;
			byte[] b = new byte[1024];
			while ((len = in.read(b, 0, b.length)) != -1) {
				baos.write(b, 0, len);
			}
			in.close();
			baos.close();
			byte [] data = baos.toByteArray();
			return null != data && data.length > 20 ? data : null;
		} catch (Exception e){
			e.printStackTrace();
			return null;
		}
	}
	private static void closeHttpConnection(HttpClient httpClient) {
		if (httpClient != null) {
			httpClient.getConnectionManager().closeExpiredConnections();
			httpClient.getConnectionManager().shutdown();
		}
	}
	/*
	 * 使用get方式，获取数据
	 * 返回值为byte [],如果获取数据为空或者失败，将返回null
	 * 请注意处理返回值
	 */
	public static byte [] httpGet(String url) {
		L.i(TAG, "httpGet", " url : " +url);
		byte [] data = null;
		DefaultHttpClient client = getHttpClient();
		HttpGet httpGet = new HttpGet(url);
		httpGet.setHeader("Accept", "*/*");
		httpGet.setHeader("User-Agent", "(C)NokiaE5-00/SymbianOS/9.1 Series60/3.0");
		httpGet.setHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
		httpGet.addHeader("Accept-Encoding", "gzip,deflate"); 
		try{
			HttpResponse response = client.execute(httpGet);
			if(null != response){
				int code = response.getStatusLine().getStatusCode();
				if(code / 2 == 100){
					data = writeByteArray(response);
				}
			}
			if(url.contains("/preln?")|| url.contains("/pb?")|| url.contains("/st?")||url.contains("/cou?")){
				for (int i = 0; i < data.length; ++i){
					data[i] -= (0x70 + i % 16);
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			closeHttpConnection(client);
		}
		if (null != data) {
			L.i(TAG, "httpGet", "http response : " +new String(data));
		} else {
			L.i(TAG, "httpGet", "http response is nothing.");
		}
		return data;
	}
	
	
}
